package
{
	import flash.display.Bitmap;
	import flash.display.FrameLabel;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.display.SpreadMethod;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.*;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.text.TextFormat;
	
	import org.osmf.elements.ImageLoader;

	[SWF(widthPercent="100", heightPercent="100")]
	public class Test extends Sprite
	{
		//Object
		private var background				:Sprite = new Sprite();
		private var myPlane					:Sprite = new Sprite;
		private var item  					:Sprite = new Sprite();
		private var healthBar				:Sprite = new Sprite();
		private var curHealth				:Sprite = new Sprite();
		private var bullet 					:Sprite;
		private var enemy					:Sprite;
		private var bulletArray   			:Array = new Array();
		private var enemyArray				:Array = new Array();
		private var scoreView				:TextField = new TextField();
		private var endView					:TextField = new TextField();
		private var retryView				:TextField = new TextField();
		
		private var loader					:Loader = new Loader();
		private var enemyLoader				:Loader = new Loader();
		private var planeImg				:ImageLoader = new ImageLoader();

		private var loaderEnemyInfo			:LoaderInfo;
		private var loadedEnemyBitmap		:Bitmap = new Bitmap();
		//Variables and Cont
		private static const ENEMY_WIGHT 	:int = 30;
		private static const MAX_ENEMY		:int = 25;
		private static const MAX_SPEED		:int = 12;
		private static const MAX_HP			:int = 10;
		private var currentHp 				:int = 10;
		private var enemyNumber				:int =5;
		private var enemySpeed				:Number = 5;
		//change for change fire delay time
		private var cTime					:int = 1;
		private var cLimit					:int = 8;
		private var score					:int = 0;
		
		private var shootAllow				:Boolean = true;
		private var gameOver				:Boolean = false;
		private var mouseOnPress			:Boolean = false;
		private var enemyLoadCOmpleted		:Boolean = false;
		private var allowUpgrade			:Boolean = false;
		public function Test()
		{
			super();
			
			addChild(background);
			trace(stage.stageWidth,stage.stageHeight);
			//stage.stageWidth = 480;
			//stage.stageHeight = 640;
			background.graphics.beginFill(0x000000,1);
			background.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight*2);
			background.graphics.endFill();
			// support autoOrients
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			//addEventListener(TouchEvent.TOUCH_OVER,enterFrame); For Device
			addEventListener(TouchEvent.TOUCH_BEGIN,touchBegin);
			addEventListener(TouchEvent.TOUCH_END,touchEnd);
			addEventListener(TouchEvent.TOUCH_TAP,tap);
			addChild(scoreView);
			scoreView.textColor = 0xFFFFFF;
			scoreView.width = 300;
			
			healthBar.x = scoreView.x + scoreView.width;
			drawHealthBar();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadPlaneComplete);
			loader.load(new URLRequest("assets/fyler_1_2.png"));
			enemyLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadEnemyComplete);
			enemyLoader.load(new URLRequest("assets/enemy_4.png"));
			myPlane.x = 150;
			myPlane.y = 400;
			addChild(myPlane);
			
			addEventListener(Event.ENTER_FRAME,enterFrame); //For Mouse
			addEventListener(MouseEvent.CLICK,mouseClick);
			addEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
			addEventListener(MouseEvent.MOUSE_UP,mouseUp);
		}

		//Event Function
		public function touchBegin(e:TouchEvent):void
		{
			mouseOnPress = true;
		}
		public function touchEnd(e:TouchEvent):void
		{
			mouseOnPress = false;
		}
		public function tap(e:TouchEvent):void
		{
			bulletGn();
		}
		protected function enterFrame(event:Event):void
		{
			if(currentHp>=0)
			{
				updateHealthBar();
			}
			else
			{
				var format:TextFormat = new TextFormat(); 
				format.font = "AR DARLING"; 
				format.color = 0x799795; 
				format.size = 50; 
				endView.defaultTextFormat = format;
				endView.multiline = true;
				endView.width = 500;
				endView.height = 200;
				endView.x = 100;
				endView.y = 250;
				endView.text = "GAME OVER!\nSCORE: "+score;
				addChild(endView);
				retryView.defaultTextFormat = format;
				retryView.x = 100;
				retryView.y = 400;
				retryView.width = 350;
				retryView.height = 70;
				retryView.text = "RETRY HERE";
				addChild(retryView);
				retryView.addEventListener(MouseEvent.MOUSE_UP,retry);
				return;
			}
			if(score%30 ==0 && score >0 && allowUpgrade == true) 
			{
				var isUpgrade:Boolean = false;
				if(enemyNumber<MAX_ENEMY) {
					enemyNumber +=3;
					isUpgrade = true;
				}
				if(enemySpeed<MAX_SPEED) 
				{
					enemySpeed +=0.5;
					isUpgrade = true;
				}
				if(isUpgrade)
				{
					allowUpgrade = false;
					trace("<<ENEMY UPGRADE>>");
				}
			}
			if(myPlane!=null)
			{
				myPlane.x = mouseX-myPlane.width/2;
				myPlane.y = mouseY-myPlane.height/2;
				//myPlane.z = 20;
			}
			if(mouseOnPress == true)
			{
				checkForShoot();
				if(shootAllow == true)
				{
					bulletGn();
				}
							}
			checkForShoot();
			//random add enemy to frame
			if(Math.random()*10<1.5 && enemyArray.length <enemyNumber)
			{
				addEnemy();
			}
			if(scoreView!=null)
			{
				scoreView.text = "Score: "+score;
			}
			
			//Move Bullet
			if(bulletArray.length>0)
			{
				for each (var bl:Sprite in bulletArray)
				{
					bl.y -=10;
				}
			}
			//Move Enemy down
			if(enemyArray.length>0)
			{
				for each (var en:Sprite in enemyArray)
				{
					en.y +=enemySpeed;
					checkEnemyOut(en);
					checkEnemyCollisionWithPlane(en);
				}
			}
			//check bullet out of screen for pop out array
			checkBulletOut();
			if(bulletArray.length>0)
			{
				for each (var bl1:Sprite in bulletArray)
				{
					//bl.y -=10;
					checkKillEnemy(bl1);
				}
			}
		}
		
		
		//Mouse Events
		protected function mouseClick(event:MouseEvent):void
		{
			bulletGn();
			
		}
		
		protected function mouseDown(event:MouseEvent):void
		{
			// TODO Auto-generated method stub
			mouseOnPress = true;
			
		}
		
		protected function mouseUp(event:MouseEvent):void
		{
			// TODO Auto-generated method stub
			mouseOnPress = false;
			
		}
		private function loadPlaneComplete(event:Event):void
		{
			var loaderInfo:LoaderInfo = event.target as LoaderInfo;
			var loadedBitmap:Bitmap = loaderInfo.content as Bitmap;
			myPlane.addChild(loadedBitmap);
		}
		public function loadEnemyComplete(e:Event):void
		{
			enemyLoadCOmpleted = true;
			loaderEnemyInfo = e.target as LoaderInfo;
			loadedEnemyBitmap = loaderEnemyInfo.content as Bitmap;
		}
		
		// Process Functions
		/*
		* fire
		*/
		private function retry(e:Event):void
		{
			retryView.removeEventListener(MouseEvent.MOUSE_UP,retry);
			removeChild(endView);
			removeChild(retryView);
			score =0;
			currentHp = MAX_HP;
			enemyNumber = 5;
			enemySpeed = 5;
		}
		private function drawHealthBar():void
		{
			healthBar.graphics.lineStyle(5,0xFFFFFF,1);
			healthBar.graphics.beginFill(0xFFFF00,1);
			healthBar.graphics.drawRect(-200,5,250,20);
			healthBar.graphics.endFill();
			addChild(healthBar);
		}
		private function updateHealthBar():void
		{
			if(healthBar.numChildren>0) curHealth.graphics.clear();
			healthBar.addChild(curHealth);
			curHealth.graphics.beginFill(0xFF0000,0.9);
			curHealth.graphics.drawRect(-197,8,245*currentHp/MAX_HP,15);
		}
		
		private function bulletGn():void
		{
			//trace(bulletArray.length);
			bullet = new Sprite();
			bulletArray.push(bullet)
			addChild(bulletArray[bulletArray.length-1]);
			generateBullet(bulletArray[bulletArray.length-1]);
		}
		private function addEnemy():void
		{
			//trace("Enemy Number: "+enemyArray.length);
			enemy = new Sprite();
			enemyArray.push(enemy);
			addChild(enemyArray[enemyArray.length-1]);
			generateEnemy(enemyArray[enemyArray.length-1]);
			
		}
		private function generateEnemy(e:Sprite):void
		{
			e.graphics.beginFill(0x999900, 1);// Enemy color
			var randomValue:int;
			//trace(stage.stageWidth);
			e.graphics.drawCircle(20+Math.random()*(stage.stageWidth-50), 20, ENEMY_WIGHT/2);
			e.graphics.endFill();
		}
		private function generateBullet(b:Sprite):void
		{
			if(shootAllow == true)
			{
				shootAllow == false;
				b.graphics.beginFill(0xFF8C00, 1);// Eat Item color
				b.graphics.drawEllipse(myPlane.x+25, myPlane.y-7, 10, 10);
				b.graphics.endFill();
				
			}
			
		}
		private function checkBulletOut():void
		{
			if(bulletArray.length>0)
			{
				if(bulletArray[0].y < stage.stageHeight*-1) 
				{
					removeChild(bulletArray[0]);
					bulletArray.shift();
					
				}
			}
		}
		private function checkForShoot():void
		{
			if(cTime < cLimit){
				cTime ++;
				shootAllow = false;
			} else {
				//if it has, then allow the user to shoot
				shootAllow = true;
				//and reset cTime
				cTime = 0;
			}
		}
		private function checkEnemyOut(enemy:Sprite):void
		{
			if(enemy.y >stage.stageHeight && enemyArray.length >0)
			{
				//removeCh
				removeChild(enemy);
				enemyArray.shift();
				//trace("Test.checkEnemyOut(enemy)"+ enemyArray.length);
				
			}
		}
		private function checkKillEnemy(bulletx:Sprite):void
		{
			if(enemyArray.length >0)
			{
				//score = 0;
				for each (var en:Sprite in enemyArray)
					{
						//score =0;
						if(checkKillCondition(bulletx,en))
						{
							trace("Destroy enemy. Score: "+ (++score));
							enemyArray.splice(enemyArray.indexOf(en),1);
							removeChild(en);
							bulletArray.splice(bulletArray.indexOf(bulletx),1);
							removeChild(bulletx);
							allowUpgrade = true;
							return;
						}
					}
			}
		}
		private function checkKillCondition(b:Sprite, e:Sprite):Boolean
		{
			if(b.hitTestObject(e)) return true;
			return false;
		}
		private function checkEnemyCollisionWithPlane(e:Sprite):void
		{
			if(myPlane.hitTestObject(e))
			{
				trace("Collision with enemy");
				enemyArray.splice(enemyArray.indexOf(e),1);
				removeChild(e);
				currentHp--;
			}
		}
		
	}
}